{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# IMDB"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from fastai.text.all import *\n",
    "from nbdev.showdoc import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preparing the data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First let's download the dataset we are going to study. The [dataset](http://ai.stanford.edu/~amaas/data/sentiment/) has been curated by Andrew Maas et al. and contains a total of 100,000 reviews on IMDB. 25,000 of them are labelled as positive and negative for training, another 25,000 are labelled for testing (in both cases they are highly polarized). The remaning 50,000 is an additional unlabelled data (but we will find a use for it nonetheless).\n",
    "\n",
    "We'll begin with a sample we've prepared for you, so that things run quickly before going over the full dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#8) [Path('/home/sgugger/.fastai/data/imdb_sample/texts.csv'),Path('/home/sgugger/.fastai/data/imdb_sample/export_lm.pkl'),Path('/home/sgugger/.fastai/data/imdb_sample/models'),Path('/home/sgugger/.fastai/data/imdb_sample/data_save.pkl'),Path('/home/sgugger/.fastai/data/imdb_sample/export.pkl'),Path('/home/sgugger/.fastai/data/imdb_sample/export_clas.pkl'),Path('/home/sgugger/.fastai/data/imdb_sample/data_clas_export.pkl'),Path('/home/sgugger/.fastai/data/imdb_sample/data_lm_export.pkl')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path = untar_data(URLs.IMDB_SAMPLE)\n",
    "path.ls()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It only contains one csv file, let's have a look at it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>label</th>\n",
       "      <th>text</th>\n",
       "      <th>is_valid</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>negative</td>\n",
       "      <td>Un-bleeping-believable! Meg Ryan doesn't even look her usual pert lovable self in this, which normally makes me forgive her shallow ticky acting schtick. Hard to believe she was the producer on this dog. Plus Kevin Kline: what kind of suicide trip has his career been on? Whoosh... Banzai!!! Finally this was directed by the guy who did Big Chill? Must be a replay of Jonestown - hollywood style. Wooofff!</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>positive</td>\n",
       "      <td>This is a extremely well-made film. The acting, script and camera-work are all first-rate. The music is good, too, though it is mostly early in the film, when things are still relatively cheery. There are no really superstars in the cast, though several faces will be familiar. The entire cast does an excellent job with the script.&lt;br /&gt;&lt;br /&gt;But it is hard to watch, because there is no good end to a situation like the one presented. It is now fashionable to blame the British for setting Hindus and Muslims against each other, and then cruelly separating them into two countries. There is som...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>negative</td>\n",
       "      <td>Every once in a long while a movie will come along that will be so awful that I feel compelled to warn people. If I labor all my days and I can save but one soul from watching this movie, how great will be my joy.&lt;br /&gt;&lt;br /&gt;Where to begin my discussion of pain. For starters, there was a musical montage every five minutes. There was no character development. Every character was a stereotype. We had swearing guy, fat guy who eats donuts, goofy foreign guy, etc. The script felt as if it were being written as the movie was being shot. The production value was so incredibly low that it felt li...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>positive</td>\n",
       "      <td>Name just says it all. I watched this movie with my dad when it came out and having served in Korea he had great admiration for the man. The disappointing thing about this film is that it only concentrate on a short period of the man's life - interestingly enough the man's entire life would have made such an epic bio-pic that it is staggering to imagine the cost for production.&lt;br /&gt;&lt;br /&gt;Some posters elude to the flawed characteristics about the man, which are cheap shots. The theme of the movie \"Duty, Honor, Country\" are not just mere words blathered from the lips of a high-brassed offic...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>negative</td>\n",
       "      <td>This movie succeeds at being one of the most unique movies you've seen. However this comes from the fact that you can't make heads or tails of this mess. It almost seems as a series of challenges set up to determine whether or not you are willing to walk out of the movie and give up the money you just paid. If you don't want to feel slighted you'll sit through this horrible film and develop a real sense of pity for the actors involved, they've all seen better days, but then you realize they actually got paid quite a bit of money to do this and you'll lose pity for them just like you've alr...</td>\n",
       "      <td>False</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      label  \\\n",
       "0  negative   \n",
       "1  positive   \n",
       "2  negative   \n",
       "3  positive   \n",
       "4  negative   \n",
       "\n",
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      text  \\\n",
       "0                                                                                                                                                                                                    Un-bleeping-believable! Meg Ryan doesn't even look her usual pert lovable self in this, which normally makes me forgive her shallow ticky acting schtick. Hard to believe she was the producer on this dog. Plus Kevin Kline: what kind of suicide trip has his career been on? Whoosh... Banzai!!! Finally this was directed by the guy who did Big Chill? Must be a replay of Jonestown - hollywood style. Wooofff!   \n",
       "1  This is a extremely well-made film. The acting, script and camera-work are all first-rate. The music is good, too, though it is mostly early in the film, when things are still relatively cheery. There are no really superstars in the cast, though several faces will be familiar. The entire cast does an excellent job with the script.<br /><br />But it is hard to watch, because there is no good end to a situation like the one presented. It is now fashionable to blame the British for setting Hindus and Muslims against each other, and then cruelly separating them into two countries. There is som...   \n",
       "2  Every once in a long while a movie will come along that will be so awful that I feel compelled to warn people. If I labor all my days and I can save but one soul from watching this movie, how great will be my joy.<br /><br />Where to begin my discussion of pain. For starters, there was a musical montage every five minutes. There was no character development. Every character was a stereotype. We had swearing guy, fat guy who eats donuts, goofy foreign guy, etc. The script felt as if it were being written as the movie was being shot. The production value was so incredibly low that it felt li...   \n",
       "3  Name just says it all. I watched this movie with my dad when it came out and having served in Korea he had great admiration for the man. The disappointing thing about this film is that it only concentrate on a short period of the man's life - interestingly enough the man's entire life would have made such an epic bio-pic that it is staggering to imagine the cost for production.<br /><br />Some posters elude to the flawed characteristics about the man, which are cheap shots. The theme of the movie \"Duty, Honor, Country\" are not just mere words blathered from the lips of a high-brassed offic...   \n",
       "4  This movie succeeds at being one of the most unique movies you've seen. However this comes from the fact that you can't make heads or tails of this mess. It almost seems as a series of challenges set up to determine whether or not you are willing to walk out of the movie and give up the money you just paid. If you don't want to feel slighted you'll sit through this horrible film and develop a real sense of pity for the actors involved, they've all seen better days, but then you realize they actually got paid quite a bit of money to do this and you'll lose pity for them just like you've alr...   \n",
       "\n",
       "   is_valid  \n",
       "0     False  \n",
       "1     False  \n",
       "2     False  \n",
       "3     False  \n",
       "4     False  "
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(path/'texts.csv')\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'This is a extremely well-made film. The acting, script and camera-work are all first-rate. The music is good, too, though it is mostly early in the film, when things are still relatively cheery. There are no really superstars in the cast, though several faces will be familiar. The entire cast does an excellent job with the script.<br /><br />But it is hard to watch, because there is no good end to a situation like the one presented. It is now fashionable to blame the British for setting Hindus and Muslims against each other, and then cruelly separating them into two countries. There is some merit in this view, but it\\'s also true that no one forced Hindus and Muslims in the region to mistreat each other as they did around the time of partition. It seems more likely that the British simply saw the tensions between the religions and were clever enough to exploit them to their own ends.<br /><br />The result is that there is much cruelty and inhumanity in the situation and this is very unpleasant to remember and to see on the screen. But it is never painted as a black-and-white case. There is baseness and nobility on both sides, and also the hope for change in the younger generation.<br /><br />There is redemption of a sort, in the end, when Puro has to make a hard choice between a man who has ruined her life, but also truly loved her, and her family which has disowned her, then later come looking for her. But by that point, she has no option that is without great pain for her.<br /><br />This film carries the message that both Muslims and Hindus have their grave faults, and also that both can be dignified and caring people. The reality of partition makes that realisation all the more wrenching, since there can never be real reconciliation across the India/Pakistan border. In that sense, it is similar to \"Mr & Mrs Iyer\".<br /><br />In the end, we were glad to have seen the film, even though the resolution was heartbreaking. If the UK and US could deal with their own histories of racism with this kind of frankness, they would certainly be better off.'"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['text'][1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It contains one line per review, with the label ('negative' or 'positive'), the text and a flag to determine if it should be part of the validation set or the training set.\n",
    "\n",
    "First, we need to tokenize the texts in our dataframe, which means separate the sentences in individual tokens (often words)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tokenization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first step of processing we make the texts go through is to split the raw sentences into words, or more exactly tokens. The easiest way to do this would be to split the string on spaces, but we can be smarter:\n",
    "\n",
    "- we need to take care of punctuation\n",
    "- some words are contractions of two different words, like isn't or don't\n",
    "- we may need to clean some parts of our texts, if there's HTML code for instance"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The texts are truncated at 100 tokens for more readability. We can see that it did more than just split on space and punctuation symbols: \n",
    "- the \"'s\" are grouped together in one token\n",
    "- the contractions are separated like this: \"did\", \"n't\"\n",
    "- content has been cleaned for any HTML symbol and lower cased\n",
    "- there are several special tokens (all those that begin by xx), to replace unknown tokens (see below) or to introduce different text fields (here we only have one)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Numericalization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Once we have extracted tokens from our texts, we convert to integers by creating a list of all the words used. We only keep the ones that appear at least twice with a maximum vocabulary size of 60,000 (by default) and replace the ones that don't make the cut by the unknown token `UNK`.\n",
    "\n",
    "This is done automatically behind the scenes if we use a facotry method of `TextDataLoaders`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dbunch_lm = TextDataLoaders.from_df(df, text_col='text', label_col='label', path=path, is_lm=True, valid_col='is_valid')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And if we look at what a what's in our datasets, we'll see the numericalized text as a representation:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([   2,    8,   21,   29, 2190,   47,  138,   44,   14,    9,  111,  908,\n",
       "          126,   33,  178,  136,   11,    8,  237,   21,  269,   51,    9,  196,\n",
       "           20,   33,  206,   37,  114, 1488,   57,    0,   14,   21,  792,   11,\n",
       "            8,   17,  222,  201,   27,   13,  219,   14, 4512,  282,   71,   15,\n",
       "         3306,  812,   57,   39,   33,   38, 1065,   15, 1173,   60,   14,    9,\n",
       "           29,   12,  248,   71,    9,  377,   33,   58, 1578,   11,    8,   59,\n",
       "           33,   61,   37,  197,   15,  252,    0,   33,  227,  793,  155,   21,\n",
       "          587,   32,   12, 2042,   13,  175,  288,   14, 1655,   28,    9,  177,\n",
       "          691,   10,   45,  178,   46,  136,  139,  482,   10,   31,  112,   33,\n",
       "         1023,   45,  174,  211, 1578,  186,   13,  224,   14,  377,   15,   61,\n",
       "           21,   12,   33,  227, 1355, 1655,   28,  118,   58,   50,   33,  178,\n",
       "          378,  257,   28,    9,   32,   11,   19,  206,   37,  158,   35,  208,\n",
       "           56,   21,  587,   29,   10,  110,  222,  156,   20,    8, 1774,    8,\n",
       "         2043,   74,   42,  116,   12,   18,   20,  376,   17, 1356,   74,   42,\n",
       "          107,   41, 1174,   11,   26,    8,   15,  345,   33,   38,  746,   15,\n",
       "          793,  155,   49,  813,  493,    9, 1175,   14,   86,   33,  178,  123,\n",
       "          136,  120,  535,   10,   21,  173,   66,  211,   15,   43,  483,  253,\n",
       "          255,   11,    8,   35,  349,   14,   20,   17,   16, 3824,   10,   27,\n",
       "           15, 1579,   20,   33,    9,  588,   83,   39,  301,   11,    8,  112,\n",
       "           91, 1024,    8,  508,   11,    8,    0,   12,    9,    0,   14,  389,\n",
       "          449,  235,    0,   10,   17,   16,   27,   59,   40,   16, 5470, 2929,\n",
       "           15,  100,  449,   35,   15,    9,   29, 2930, 5471,  501,   11,    8,\n",
       "          624,   91, 1024,    8, 1489,    8,    0,   10,   53,   19, 3825,  423,\n",
       "           34,   12,   40,   95,   41,  147,   39,   15, 5472,   18,   21,   31,\n",
       "         1416,   40,   95,   11,    8,  112,  269,    9, 2191, 2044,   10,    8,\n",
       "         3826,    8, 5473,  509,   49, 1176,  260,   10,  432,  385,  213,   55,\n",
       "            8, 3826,    8, 5473,   16,   39,   13,   70, 1289,  710,   12,  856,\n",
       "           73,    0,  235,  570,   18,  126,   10,   18,   82,  589,  165,   73,\n",
       "          149,  909,   15,  126,   14,    9,    8,  294, 3827,  674,   11,   26,\n",
       "            8,   46,   18,   46,   33,   58,  223,  197,   15,   88,   21,   28,\n",
       "          613,   72,   17,  269,   60,   35,  348,   10,   19,  144,   20,   19,\n",
       "          211,   13, 2405,   60,   14,   17,   10,   19,  473, 1656,   46,   43,\n",
       "         1290,  142,   10,  515,  110, 5474,   15,    0,   18,    9, 4513,   14,\n",
       "          350,   11]),)"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dbunch_lm.train_ds[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The correspondence is stored in the vocab attribute of our `DataLoaders`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['xxunk',\n",
       " 'xxpad',\n",
       " 'xxbos',\n",
       " 'xxeos',\n",
       " 'xxfld',\n",
       " 'xxrep',\n",
       " 'xxwrep',\n",
       " 'xxup',\n",
       " 'xxmaj',\n",
       " 'the',\n",
       " ',',\n",
       " '.',\n",
       " 'and',\n",
       " 'a',\n",
       " 'of',\n",
       " 'to',\n",
       " 'is',\n",
       " 'it',\n",
       " 'in',\n",
       " 'i']"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dbunch_lm.vocab[:20]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>text_</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>xxbos … said a couple xxunk the movie theater just as i was entering to watch this . xxmaj hmm , not a good sign , but who knows ? xxmaj different xxunk for different folks , after all . xxmaj well , nope . xxmaj they were being kind . xxmaj godard has released work that is passionate ( contempt ) , entertaining ( band of xxmaj outsiders ) , sometimes</td>\n",
       "      <td>… said a couple xxunk the movie theater just as i was entering to watch this . xxmaj hmm , not a good sign , but who knows ? xxmaj different xxunk for different folks , after all . xxmaj well , nope . xxmaj they were being kind . xxmaj godard has released work that is passionate ( contempt ) , entertaining ( band of xxmaj outsiders ) , sometimes both</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>the lake to xxunk ? xxmaj other than some token fog in one or two scenes , we see no evidence of the water being hot , other than a few lines in the script . \\n\\n xxmaj the script is xxunk rather obviously in a few sequences , and it will do anything to get the characters near the lake so that they can be xxunk by the claymation xxunk .</td>\n",
       "      <td>lake to xxunk ? xxmaj other than some token fog in one or two scenes , we see no evidence of the water being hot , other than a few lines in the script . \\n\\n xxmaj the script is xxunk rather obviously in a few sequences , and it will do anything to get the characters near the lake so that they can be xxunk by the claymation xxunk . a</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>. 's intelligence . xxup t.k . is torn between his own xxunk and his xxunk background . xxmaj sajani is a woman xxunk of having a choice in her romantic life . xxmaj oh , and , of course , xxmaj moores ' family is xxunk into xxmaj sajani 's death but still slightly racist to xxmaj indians . xxmaj if the tone was n't so serious , i would be</td>\n",
       "      <td>'s intelligence . xxup t.k . is torn between his own xxunk and his xxunk background . xxmaj sajani is a woman xxunk of having a choice in her romantic life . xxmaj oh , and , of course , xxmaj moores ' family is xxunk into xxmaj sajani 's death but still slightly racist to xxmaj indians . xxmaj if the tone was n't so serious , i would be willing</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>nowadays . xxmaj it 's like all you need is a camera , a group of people to be your cast and crew , a script , and a little money and xxunk you have a movie . xxmaj problem is that talent is n't always part of this xxunk and often times these kind of low budget films turn out to be duds . xxmaj the video store xxunk are filled</td>\n",
       "      <td>. xxmaj it 's like all you need is a camera , a group of people to be your cast and crew , a script , and a little money and xxunk you have a movie . xxmaj problem is that talent is n't always part of this xxunk and often times these kind of low budget films turn out to be duds . xxmaj the video store xxunk are filled with</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>for xxmaj major xxmaj payne even though he xxunk the kids poorly , has no social skills and is simply impossible to xxunk into someone you would want to spend time with . xxmaj she must either be incredibly stupid or incredibly desperate . xxmaj i 'm not sure which ( though it would seem \" stupid \" since the movie makes it clear she gets out of the house often enough</td>\n",
       "      <td>xxmaj major xxmaj payne even though he xxunk the kids poorly , has no social skills and is simply impossible to xxunk into someone you would want to spend time with . xxmaj she must either be incredibly stupid or incredibly desperate . xxmaj i 'm not sure which ( though it would seem \" stupid \" since the movie makes it clear she gets out of the house often enough )</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>xxmaj boeing . \" xxmaj the original author of that work , xxmaj marc xxmaj xxunk , is credited nowhere . xxmaj at least xxmaj priyadarshan changed the title for this remake , rather than xxunk using the original without giving credit , as he did in his xxunk version of this same tale . ( according to imdb 's credits list . ) xxbos xxmaj what i think xxmaj i 'll</td>\n",
       "      <td>boeing . \" xxmaj the original author of that work , xxmaj marc xxmaj xxunk , is credited nowhere . xxmaj at least xxmaj priyadarshan changed the title for this remake , rather than xxunk using the original without giving credit , as he did in his xxunk version of this same tale . ( according to imdb 's credits list . ) xxbos xxmaj what i think xxmaj i 'll probably</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>relationship between xxmaj frankie and her grandmother is convincing , but the relationship between xxmaj hazel and xxmaj frankie is a bit … off . xxmaj it 's interesting to see how she has to work hard to keep a balance between her best friend , her grandmother , and her two xxunk : ballet and baseball . xxmaj being a baseball player myself , it was quite painful to watch xxmaj</td>\n",
       "      <td>between xxmaj frankie and her grandmother is convincing , but the relationship between xxmaj hazel and xxmaj frankie is a bit … off . xxmaj it 's interesting to see how she has to work hard to keep a balance between her best friend , her grandmother , and her two xxunk : ballet and baseball . xxmaj being a baseball player myself , it was quite painful to watch xxmaj frankie</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>the genre with open arms . \\n\\n xxmaj xxunk is xxunk as the menacing , damn sexy , but vicious and mean bitch who xxunk out an entire police force and poor xxmaj tanya 's parents in one fail xxunk , in less than ten or so minutes . xxmaj she stabs one in the back with a xxunk xxunk ! xxmaj she bites the fingers off of poor xxmaj ron xxmaj</td>\n",
       "      <td>genre with open arms . \\n\\n xxmaj xxunk is xxunk as the menacing , damn sexy , but vicious and mean bitch who xxunk out an entire police force and poor xxmaj tanya 's parents in one fail xxunk , in less than ten or so minutes . xxmaj she stabs one in the back with a xxunk xxunk ! xxmaj she bites the fingers off of poor xxmaj ron xxmaj xxunk</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>one of them ( \" xxunk : xxmaj fighting xxmaj edition \" ) , which was xxup really sad . xxmaj anyway , it was the show that set a stepping stone on my interest on robot series ( especially anime xxunk series like \" gundam \" ) xxmaj now that xxmaj i 'm 18 , xxmaj i 'd like to think this show is pretty cheesy to me now . xxmaj</td>\n",
       "      <td>of them ( \" xxunk : xxmaj fighting xxmaj edition \" ) , which was xxup really sad . xxmaj anyway , it was the show that set a stepping stone on my interest on robot series ( especially anime xxunk series like \" gundam \" ) xxmaj now that xxmaj i 'm 18 , xxmaj i 'd like to think this show is pretty cheesy to me now . xxmaj to</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dbunch_lm.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### With the data block API"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can use the data block API with NLP and have a lot more flexibility than what the default factory methods offer. In the previous example for instance, the data was randomly split between train and validation instead of reading the third column of the csv.\n",
    "\n",
    "With the data block API though, we have to manually call the tokenize and numericalize steps. This allows more flexibility, and if you're not using the defaults from fastai, the various arguments to pass will appear in the step they're revelant, so it'll be more readable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "imdb_lm = DataBlock(blocks=(TextBlock.from_df('text', is_lm=True),),\n",
    "                    get_x=ColReader('text'),\n",
    "                    splitter=RandomSplitter())\n",
    "\n",
    "dbunch_lm = imdb_lm.dataloaders(df)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Language model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that language models can use a lot of GPU, so you may need to decrease batchsize here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bs=128"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's grab the full dataset for what follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#7) [Path('/home/sgugger/.fastai/data/imdb/unsup'),Path('/home/sgugger/.fastai/data/imdb/imdb.vocab'),Path('/home/sgugger/.fastai/data/imdb/tmp_lm'),Path('/home/sgugger/.fastai/data/imdb/train'),Path('/home/sgugger/.fastai/data/imdb/test'),Path('/home/sgugger/.fastai/data/imdb/README'),Path('/home/sgugger/.fastai/data/imdb/tmp_clas')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "path = untar_data(URLs.IMDB)\n",
    "path.ls()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(#4) [Path('/home/sgugger/.fastai/data/imdb/train/pos'),Path('/home/sgugger/.fastai/data/imdb/train/unsupBow.feat'),Path('/home/sgugger/.fastai/data/imdb/train/labeledBow.feat'),Path('/home/sgugger/.fastai/data/imdb/train/neg')]"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(path/'train').ls()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The reviews are in a training and test set following an imagenet structure. The only difference is that there is an `unsup` folder on top of `train` and `test` that contains the unlabelled data.\n",
    "\n",
    "We're not going to train a model that classifies the reviews from scratch. Like in computer vision, we'll use a model pretrained on a bigger dataset (a cleaned subset of wikipedia called [wikitext-103](https://einstein.ai/research/blog/the-wikitext-long-term-dependency-language-modeling-dataset)). That model has been trained to guess what the next word is, its input being all the previous words. It has a recurrent structure and a hidden state that is updated each time it sees a new word. This hidden state thus contains information about the sentence up to that point.\n",
    "\n",
    "We are going to use that 'knowledge' of the English language to build our classifier, but first, like for computer vision, we need to fine-tune the pretrained model to our particular dataset. Because the English of the reviews left by people on IMDB isn't the same as the English of wikipedia, we'll need to adjust the parameters of our model by a little bit. Plus there might be some words that would be extremely common in the reviews dataset but would be barely present in wikipedia, and therefore might not be part of the vocabulary the model was trained on."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is where the unlabelled data is going to be useful to us, as we can use it to fine-tune our model. Let's create our data object with the data block API (next line takes a few minutes the first minute you run it)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imdb_lm = DataBlock(blocks=(TextBlock.from_folder(path, is_lm=True),),\n",
    "                    get_items=partial(get_text_files, folders=['train', 'test', 'unsup']),\n",
    "                    splitter=RandomSplitter(0.1))\n",
    "\n",
    "dbunch_lm = imdb_lm.dataloaders(path, path=path, bs=bs, seq_len=80)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to use a special kind of `TextDataLoaders` for the language model, that ignores the labels (that's why we put 0 everywhere), will shuffle the texts at each epoch before concatenating them all together (only for training, we don't shuffle for the validation set) and will send batches that read that text in order with targets that are the next word in the sentence.\n",
    "\n",
    "The line before being a bit long, we want to load quickly the final ids by using the following cell."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>text_</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>xxunk there xxunk xxunk enjoying this weird and weirdly detailed movie with weird animation and a weird mix of styles xxunk real faces photographed for the xxunk and the credits start rolling when xxunk xxunk xxunk a xxunk is this music xxunk xxunk xxunk long xxunk xxunk xxunk xxunk xxunk it is xxunk xxunk xxunk music isn't what makes a xxunk even a short animation like this xxunk but anyone who knows who xxunk xxunk is xxunk many should considering</td>\n",
       "      <td>there xxunk xxunk enjoying this weird and weirdly detailed movie with weird animation and a weird mix of styles xxunk real faces photographed for the xxunk and the credits start rolling when xxunk xxunk xxunk a xxunk is this music xxunk xxunk xxunk long xxunk xxunk xxunk xxunk xxunk it is xxunk xxunk xxunk music isn't what makes a xxunk even a short animation like this xxunk but anyone who knows who xxunk xxunk is xxunk many should considering the</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>not one for educational xxunk but this one grabs hold of you and doesn't let go until the xxunk xxunk be so hooked and entranced by what you are watching that you'll forget your at home watching xxunk xxunk series is available to buy on xxunk and xxunk xxunk recommend picking this one xxunk xxunk all the evil and death in this xxunk this documentary series gives us proof that life is beautiful and worth saving and xxunk xxunk main</td>\n",
       "      <td>one for educational xxunk but this one grabs hold of you and doesn't let go until the xxunk xxunk be so hooked and entranced by what you are watching that you'll forget your at home watching xxunk xxunk series is available to buy on xxunk and xxunk xxunk recommend picking this one xxunk xxunk all the evil and death in this xxunk this documentary series gives us proof that life is beautiful and worth saving and xxunk xxunk main attraction</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>the xxunk in new xxunk xxunk movie is no xxunk xxunk uses the blueprint of con movie elements with little new xxunk xxunk is a xxunk one ya seen 'em xxunk con game xxunk xxunk xxunk newer ones just add a few more unimaginative side xxunk involve modern devices such as electronic xxunk computer xxunk a little more of the sex xxunk xxunk complicating a tired plot doesn't make it xxunk xxunk back we had a list of worst movies</td>\n",
       "      <td>xxunk in new xxunk xxunk movie is no xxunk xxunk uses the blueprint of con movie elements with little new xxunk xxunk is a xxunk one ya seen 'em xxunk con game xxunk xxunk xxunk newer ones just add a few more unimaginative side xxunk involve modern devices such as electronic xxunk computer xxunk a little more of the sex xxunk xxunk complicating a tired plot doesn't make it xxunk xxunk back we had a list of worst movies ever</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>film has the same sort of premise from there xxunk xxunk xxunk i have mentioned the ending is xxunk it isn't very believable xxunk at xxunk why would bloody bill believe that gwen was his sister and the fact that they look xxunk like each other isn't very plausible xxunk and it would have been nice to find out what happened to gwen after she left death xxunk xxunk xxunk hope their isn't a sequel as zombie sequels are never</td>\n",
       "      <td>has the same sort of premise from there xxunk xxunk xxunk i have mentioned the ending is xxunk it isn't very believable xxunk at xxunk why would bloody bill believe that gwen was his sister and the fact that they look xxunk like each other isn't very plausible xxunk and it would have been nice to find out what happened to gwen after she left death xxunk xxunk xxunk hope their isn't a sequel as zombie sequels are never good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>xxunk afraid to chew the xxunk xxunk also had a decent xxunk xxunk one had me scratching my xxunk xxunk xxunk isn't really xxunk about a xxunk why does she have a manager xxunk why is he wasting his xxunk xxunk xxunk and xxunk are xxunk why do they sign up for xxunk xxunk of xxunk xxunk xxunk xxunk the xxunk xxunk movie where xxunk xxunk wants to do xxunk only to find himself on xxunk xxunk xxunk industry xxunk</td>\n",
       "      <td>afraid to chew the xxunk xxunk also had a decent xxunk xxunk one had me scratching my xxunk xxunk xxunk isn't really xxunk about a xxunk why does she have a manager xxunk why is he wasting his xxunk xxunk xxunk and xxunk are xxunk why do they sign up for xxunk xxunk of xxunk xxunk xxunk xxunk the xxunk xxunk movie where xxunk xxunk wants to do xxunk only to find himself on xxunk xxunk xxunk industry xxunk but</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>camera and had it trained exclusively on xxunk xxunk boys do their best routines xxunk xxunk xxunk xxunk xxunk xxunk the xxunk xxunk they are a joy to xxunk xxunk who thinks that xxunk xxunk xxunk the best straight man in the business should watch the xxunk routine and check out how he consistently and skillfully reins in xxunk whenever xxunk manic energy takes him too far outside the skit while still allowing him the freedom to employ the xxunk</td>\n",
       "      <td>and had it trained exclusively on xxunk xxunk boys do their best routines xxunk xxunk xxunk xxunk xxunk xxunk the xxunk xxunk they are a joy to xxunk xxunk who thinks that xxunk xxunk xxunk the best straight man in the business should watch the xxunk routine and check out how he consistently and skillfully reins in xxunk whenever xxunk manic energy takes him too far outside the skit while still allowing him the freedom to employ the xxunk and</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>xxunk the worse xxunk always xxunk little or no xxunk and every one was drunk or xxunk xxunk the xxunk the xxunk and the xxunk made it all worth xxunk xxunk like xxunk xxunk xxunk too damn old for it xxunk and the arthritis in the hands and hips mean no more xxunk but for the length of that xxunk it all came xxunk and it was all xxunk xxunk xxunk the xxunk and the xxunk xxunk xxunk was young</td>\n",
       "      <td>the worse xxunk always xxunk little or no xxunk and every one was drunk or xxunk xxunk the xxunk the xxunk and the xxunk made it all worth xxunk xxunk like xxunk xxunk xxunk too damn old for it xxunk and the arthritis in the hands and hips mean no more xxunk but for the length of that xxunk it all came xxunk and it was all xxunk xxunk xxunk the xxunk and the xxunk xxunk xxunk was young xxunk</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>or give detailed or coherent answers or even answers at xxunk xxunk highly doubt that if some of those who were interviewed knew what xxunk was creating or saw the final product would allow themselves to be included in the xxunk xxunk film puts punks in a bad light by making them seem unintelligent and xxunk xxunk film should not be taken as a representation of the xxunk punk xxunk xxunk you want to see a good punk documentary watch</td>\n",
       "      <td>give detailed or coherent answers or even answers at xxunk xxunk highly doubt that if some of those who were interviewed knew what xxunk was creating or saw the final product would allow themselves to be included in the xxunk xxunk film puts punks in a bad light by making them seem unintelligent and xxunk xxunk film should not be taken as a representation of the xxunk punk xxunk xxunk you want to see a good punk documentary watch xxunk</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>featured in this xxunk xxunk just a choice between a hard life with your pride or getting more money with less xxunk xxunk to the xxunk xxunk xxunk film is very sad xxunk xxunk xxunk because the xxunk is sad but because sadly there is no xxunk xxunk because the xxunk or any other artistic feature is so convincing but because of the lack of anything xxunk xxunk others have pointed out here the director obviously had nothing together before</td>\n",
       "      <td>in this xxunk xxunk just a choice between a hard life with your pride or getting more money with less xxunk xxunk to the xxunk xxunk xxunk film is very sad xxunk xxunk xxunk because the xxunk is sad but because sadly there is no xxunk xxunk because the xxunk or any other artistic feature is so convincing but because of the lack of anything xxunk xxunk others have pointed out here the director obviously had nothing together before shooting</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dbunch_lm.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then put this in a learner object very easily with a model loaded with the pretrained weights. They'll be downloaded the first time you'll execute the following line and stored in `~/.fastai/models/` (or elsewhere if you specified different paths in your config file)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "60008"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(dbunch_lm.vocab)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn = language_model_learner(dbunch_lm, AWD_LSTM, drop_mult=0.3, metrics=[accuracy, Perplexity()]).to_fp16()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LR Finder is complete, type {learner_name}.recorder.plot() to see the graph.\n"
     ]
    }
   ],
   "source": [
    "learn.lr_find()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.recorder.plot_lr_find(skip_end=15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>perplexity</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4.121422</td>\n",
       "      <td>3.914404</td>\n",
       "      <td>0.299510</td>\n",
       "      <td>50.119186</td>\n",
       "      <td>07:11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(1, 2e-2, moms=(0.8,0.7,0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('fit_head')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('fit_head');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To complete the fine-tuning, we can then unfeeze and launch a new training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.unfreeze()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>perplexity</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>3.892977</td>\n",
       "      <td>3.774952</td>\n",
       "      <td>0.316564</td>\n",
       "      <td>43.595413</td>\n",
       "      <td>07:37</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>3.814780</td>\n",
       "      <td>3.715484</td>\n",
       "      <td>0.323794</td>\n",
       "      <td>41.078480</td>\n",
       "      <td>07:41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>3.749609</td>\n",
       "      <td>3.664291</td>\n",
       "      <td>0.329369</td>\n",
       "      <td>39.028442</td>\n",
       "      <td>07:41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>3.685419</td>\n",
       "      <td>3.629105</td>\n",
       "      <td>0.333663</td>\n",
       "      <td>37.679073</td>\n",
       "      <td>07:40</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>3.618381</td>\n",
       "      <td>3.603617</td>\n",
       "      <td>0.336755</td>\n",
       "      <td>36.730846</td>\n",
       "      <td>07:41</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>5</td>\n",
       "      <td>3.567165</td>\n",
       "      <td>3.585856</td>\n",
       "      <td>0.338791</td>\n",
       "      <td>36.084221</td>\n",
       "      <td>07:46</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>6</td>\n",
       "      <td>3.503764</td>\n",
       "      <td>3.575684</td>\n",
       "      <td>0.340408</td>\n",
       "      <td>35.719028</td>\n",
       "      <td>07:47</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>7</td>\n",
       "      <td>3.453132</td>\n",
       "      <td>3.569989</td>\n",
       "      <td>0.341550</td>\n",
       "      <td>35.516193</td>\n",
       "      <td>07:49</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>8</td>\n",
       "      <td>3.409692</td>\n",
       "      <td>3.569814</td>\n",
       "      <td>0.341963</td>\n",
       "      <td>35.509995</td>\n",
       "      <td>07:56</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>9</td>\n",
       "      <td>3.384848</td>\n",
       "      <td>3.572026</td>\n",
       "      <td>0.341847</td>\n",
       "      <td>35.588623</td>\n",
       "      <td>07:58</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(10, 2e-3, moms=(0.8,0.7,0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('fine_tuned')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How good is our model? Well let's try to see what it predicts after a few given words."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('fine_tuned');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "TEXT = \"I liked this movie because\"\n",
    "N_WORDS = 40\n",
    "N_SENTENCES = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I liked this movie because of the cool scenery and the high level of xxmaj british hunting . xxmaj the only thing this movie has going for it is the horrible acting and no script . xxmaj the movie was a big disappointment . xxmaj\n",
      "I liked this movie because it was one of the few movies that made me laugh so hard i did n't like it . xxmaj it was a hilarious film and it was very entertaining . \n",
      "\n",
      " xxmaj the acting was great , i 'm\n"
     ]
    }
   ],
   "source": [
    "print(\"\\n\".join(learn.predict(TEXT, N_WORDS, temperature=0.75) for _ in range(N_SENTENCES)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to save not only the model, but also its encoder, the part that's responsible for creating and updating the hidden state. For the next part, we don't care about the part that tries to guess the next word."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save_encoder('fine_tuned_enc')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we'll create a new data object that only grabs the labelled data and keeps those labels. Again, this line takes a bit of time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_tokenized_file(f): return L(f.read_text().split(' '))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "imdb_clas = DataBlock(blocks=(TextBlock.from_folder(path, vocab=dbunch_lm.vocab),CategoryBlock),\n",
    "                      get_x=read_tokenized_file,\n",
    "                      get_y = parent_label,\n",
    "                      get_items=partial(get_text_files, folders=['train', 'test']),\n",
    "                      splitter=GrandparentSplitter(valid_name='test'))\n",
    "\n",
    "dbunch_clas = imdb_clas.dataloaders(path, path=path, bs=bs, seq_len=80)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>category</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>xxunk have praised xxunk xxunk xxunk as a xxunk adventure for xxunk xxunk don't think xxunk least not for thinking xxunk xxunk xxunk script suggests a beginning as a xxunk xxunk that struck someone as the type of crap you cannot sell to adults xxunk xxunk xxunk xxunk of many older adventure movies has been done well xxunk xxunk xxunk xxunk xxunk but xxunk represents one of the worse films in that xxunk xxunk characters are xxunk xxunk the background that each member trots out seems stock and awkward at xxunk xxunk xxunk xxunk a tomboy mechanic whose father always wanted xxunk if we have not at least seen these xxunk we have seen xxunk quirks xxunk xxunk story about how one xxunk xxunk played by xxunk xxunk xxunk xxunk xxunk went from flower stores to demolitions totally xxunk xxunk xxunk the main xxunk xxunk xxunk a young xxunk academic</td>\n",
       "      <td>neg</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>xxunk thought that xxunk was clearly the best out of the three xxunk xxunk xxunk xxunk find it surprising that xxunk is considered the weakest installment in the xxunk by many who have xxunk xxunk me it seemed like xxunk was the best because it had the most profound xxunk the most xxunk xxunk most xxunk the xxunk and definitely the most episodic xxunk xxunk personally like the xxunk xxunk xxunk a lot also but xxunk think it is slightly less good than than xxunk since it was xxunk was not as xxunk and xxunk just did not feel as much suspense or emotion as xxunk did with the third xxunk xxunk xxunk also seems like to me that after reading these surprising reviews that the reasons people cited for xxunk being an inferior film to the other two are just plain ludicrous and are insignificant reasons compared to the</td>\n",
       "      <td>pos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>xxunk the realm of xxunk xxunk two particular themes consistently elicit xxunk were initially explored in the literature of a xxunk xxunk and have since been periodically revisited by filmmakers and writers xxunk with varying degrees of xxunk xxunk first xxunk that of time xxunk has held an unwavering fascination for fans of xxunk as well as the written xxunk most recently on the screen with yet another version of the xxunk xxunk xxunk xxunk xxunk xxunk xxunk second xxunk which also manages to hold audiences in xxunk is that of xxunk which sparks the imagination with it's seemingly endless and myriad xxunk xxunk this xxunk xxunk has again become the basis for a film adapted from another xxunk xxunk xxunk xxunk xxunk xxunk the realization of xxunk xxunk is xxunk xxunk directed by xxunk xxunk and starring xxunk xxunk and xxunk xxunk xxunk xxunk xxunk xxunk and his colleagues</td>\n",
       "      <td>neg</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>xxunk xxunk makes me nostalgic for the early xxunk a time when virtually every new action movie could be described as xxunk xxunk in a xxunk xxunk xxunk is xxunk xxunk on a xxunk and pretty xxunk for what it xxunk xxunk xxunk unlike xxunk 57 and xxunk xxunk which are decent xxunk xxunk clones on their own xxunk xxunk dispenses with the enclosed feeling of many action movies and embraces breathtaking landscapes xxunk in their xxunk threaten to overwhelm and trivialize the conflicts of the people fighting and dying among the xxunk xxunk xxunk before other movies like xxunk xxunk xxunk and xxunk dramatized crime and murder on snowbound xxunk xxunk director xxunk xxunk recognized the visual impact of juxtaposing brutal violence and grim struggles to survive against cold and indifferent natural xxunk xxunk xxunk opening sequence has already received substantial xxunk all of which it xxunk its intensity</td>\n",
       "      <td>pos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>xxunk effects of job related stress and the pressures born of a moral dilemma that pits conscience against the obligations of a family business xxunk a unique xxunk all brought to a head xxunk or perhaps the catalyst xxunk a midlife xxunk are examined in the dark and absorbing xxunk xxunk written and directed by xxunk xxunk and starring xxunk xxunk xxunk and xxunk xxunk xxunk a telling look at how indecision and denial can bring about the internal strife and misery that ultimately leads to apathy and that moment of truth when the conflict xxunk of xxunk at last be xxunk xxunk xxunk xxunk is xxunk he has a loving xxunk xxunk xxunk xxunk a precocious xxunk xxunk xxunk xxunk xxunk a mail order business he runs out of the xxunk as well as his main source of xxunk the xxunk business he shares with his xxunk xxunk xxunk</td>\n",
       "      <td>pos</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>xxunk xxunk style movie takes the middle aged divorcee victim who then finally fights back genre to new depths of xxunk xxunk xxunk xxunk the 40 something xxunk xxunk of a successful lawyer protagonist xxunk away at xxunk is starting a new life after her xxunk helped by a female college friend in opening a new dress shop as a sort of franchise expansion xxunk xxunk has even started up a friendship with her xxunk slightly younger xxunk landscape architect / gardener xxunk xxunk xxunk then horror of xxunk xxunk xxunk xxunk 20 something female she took on as a tenant to let a room xxunk starts xxunk xxunk her xxunk xxunk xxunk this new younger woman threat really does is mildly flirt with the xxunk and offer him a glass of wine that * gasp * really belonged to the xxunk xxunk runs up the utility bills by not</td>\n",
       "      <td>neg</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>xxunk xxunk sadly xxunk xxunk rented xxunk xxunk on xxunk xxunk 3 several years ago and there was a music xxunk xxunk pretty sure which was called xxunk xxunk at the end of xxunk and xxunk rented this one on xxunk hoping that the video would be there because it was one of the funniest things xxunk ever xxunk xxunk amazing how stuff from the 80s is so funny xxunk but nothing is funnier than 80s rap xxunk xxunk was this rap group singing that song xxunk xxunk on the xxunk version of this movie after the xxunk and they're all wearing like denim jackets with no shirt underneath and form fitting jean shorts that are all frayed at the bottoms like xxunk xxunk xxunk could make a rap group look more foolish xxunk can't xxunk xxunk xxunk xxunk any xxunk xxunk was disappointed in looking for that video on</td>\n",
       "      <td>neg</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>xxunk have never seen any of xxunk xxunk prior xxunk as their trailers never caught my xxunk xxunk have xxunk and admire xxunk xxunk and xxunk xxunk xxunk and have several of their xxunk xxunk xxunk xxunk entirely disappointed with this xxunk xxunk this film is any indication of xxunk xxunk ability as a xxunk my advice would be to xxunk a xxunk and stop wasting the time and talent of xxunk xxunk xxunk xxunk wonder if some of the other xxunk commentators watched the same movie that xxunk xxunk xxunk can only xxunk from their sappy lovelorn xxunk that their adoration of xxunk xxunk has blinded them to the banality of this piece of xxunk xxunk only paid xxunk in a xxunk xxunk xxunk and still felt xxunk wasted my xxunk xxunk xxunk xxunk xxunk page says it xxunk xxunk xxunk xxunk in 39 xxunk -- xxunk can you</td>\n",
       "      <td>neg</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>xxunk is not as great a film as many people believe xxunk my late xxunk who said it was her favorite xxunk xxunk due to the better sections of this film xxunk particularly that justifiably famous xxunk xxunk xxunk xxunk xxunk xxunk xxunk has gained a position of importance beyond it's actual worth as a key to the saga of xxunk xxunk failure to conquer xxunk xxunk xxunk 1946 xxunk position as a xxunk figure was xxunk xxunk xxunk was not recognized as the great movie it has since been seen as due to the way it was attacked by the xxunk press and by xxunk insiders xxunk xxunk attempt at total control xxunk and production and xxunk of his movies seemed to threaten the whole xxunk xxunk best job in this period was as xxunk xxunk in xxunk xxunk supposedly shot by xxunk xxunk but actually shot in large</td>\n",
       "      <td>pos</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dbunch_clas.show_batch()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can then create a model to classify those reviews and load the encoder we saved before."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<fastai.text.learner.RNNLearner at 0x7f033cb75f10>"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "learn = text_classifier_learner(dbunch_clas, AWD_LSTM, drop_mult=0.5, metrics=accuracy).to_fp16()\n",
    "learn.load_encoder('fine_tuned_enc')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.lr_find()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.347427</td>\n",
       "      <td>0.184480</td>\n",
       "      <td>0.929320</td>\n",
       "      <td>00:33</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.fit_one_cycle(1, 2e-2, moms=(0.8,0.7, 0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('first')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('first');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.247763</td>\n",
       "      <td>0.171683</td>\n",
       "      <td>0.934640</td>\n",
       "      <td>00:37</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.freeze_to(-2)\n",
    "learn.fit_one_cycle(1, slice(1e-2/(2.6**4),1e-2), moms=(0.8,0.7, 0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('second')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('second');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.193377</td>\n",
       "      <td>0.156696</td>\n",
       "      <td>0.941200</td>\n",
       "      <td>00:45</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.freeze_to(-3)\n",
    "learn.fit_one_cycle(1, slice(5e-3/(2.6**4),5e-3),moms=(0.8,0.7, 0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.save('third')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "learn.load('third');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: left;\">\n",
       "      <th>epoch</th>\n",
       "      <th>train_loss</th>\n",
       "      <th>valid_loss</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>0.172888</td>\n",
       "      <td>0.153770</td>\n",
       "      <td>0.943120</td>\n",
       "      <td>01:01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>0.161492</td>\n",
       "      <td>0.155567</td>\n",
       "      <td>0.942640</td>\n",
       "      <td>00:57</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "learn.unfreeze()\n",
    "learn.fit_one_cycle(2, slice(1e-3/(2.6**4),1e-3), moms=(0.8,0.7, 0.8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div>\n",
       "        <style>\n",
       "            /* Turns off some styling */\n",
       "            progress {\n",
       "                /* gets rid of default border in Firefox and Opera. */\n",
       "                border: none;\n",
       "                /* Needs to be in here for Safari polyfill so background images work as expected. */\n",
       "                background-size: auto;\n",
       "            }\n",
       "            .progress-bar-interrupted, .progress-bar-interrupted::-webkit-progress-bar {\n",
       "                background: #F44336;\n",
       "            }\n",
       "        </style>\n",
       "      <progress value='0' class='' max='1', style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
       "      \n",
       "    </div>\n",
       "    "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "('pos', tensor(1), tensor([1.4426e-04, 9.9986e-01]))"
      ]
     },
     "execution_count": null,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "learn.predict(\"I really loved that movie , it was awesome !\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "split_at_heading": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
